package org.xzheng.repayment.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.xzheng.repayment.entity.ReplayPlan;
import org.xzheng.repayment.service.IRepayPlanGenerator;
import org.xzheng.repayment.util.DateUtil;

/**
 * 等额本息还款，也称定期付息，即借款人每月按相等的金额偿还贷款本息，其中每月贷款利息按月初剩余贷款本金计算并逐月结清。把按揭贷款的本金总额与利息总额相加，
 * 然后平均分摊到还款期限的每个月中。作为还款人，每个月还给银行固定金额，但每月还款额中的本金比重逐月递增、利息比重逐月递减。
 * 
 * <pre>
每月偿还本息=〔贷款本金×月利率×(1＋月利率)＾还款月数〕÷〔(1＋月利率)＾还款月数-1〕
每月偿还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕
每月偿还本金 = 每月偿还本息 - 每月偿还利息
 * </pre>
 * 
 * *
 */
public class RePayAlgorithmPrincipal implements IRepayPlanGenerator {

	@Override
	public Map<Integer, ReplayPlan> getRepayPlan(double invest, double yearRate, int totalmonth, Date begin) {
		Map<Integer, ReplayPlan> map = new HashMap<Integer, ReplayPlan>();
		double monthRate = yearRate / 12;
		DateTime before = null;
		DateTime after = null;

		DateTime beginBase = new DateTime(begin);
		beginBase = beginBase.plusDays(-1);

		// 每月偿还本息=〔贷款本金×月利率×(1＋月利率)＾还款月数〕÷〔(1＋月利率)＾还款月数-1〕
		BigDecimal monthIncome = new BigDecimal(invest)
				.multiply(new BigDecimal(monthRate * Math.pow(1 + monthRate, totalmonth)))
				.divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 2, BigDecimal.ROUND_DOWN);

		for (int i = 0; i < totalmonth; i++) {
			int period = i + 1;

			if (after == null) {
				before = new DateTime(begin);
			} else {
				before = after.plusDays(1);
			}

			after = new DateTime(DateUtil.add_month(beginBase.toDate(), period));

			int days = Days.daysBetween(before, after).getDays() + 1;

			BigDecimal multiply = new BigDecimal(invest).multiply(new BigDecimal(monthRate));
			BigDecimal sub = new BigDecimal(Math.pow(1 + monthRate, totalmonth))
					.subtract(new BigDecimal(Math.pow(1 + monthRate, i - 1)));

			// 每月偿还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕
			BigDecimal monthInterest = multiply.multiply(sub)
					.divide(new BigDecimal(Math.pow(1 + monthRate, totalmonth) - 1), 6, BigDecimal.ROUND_DOWN);
			monthInterest = monthInterest.setScale(2, BigDecimal.ROUND_DOWN);

			// 本金 = 每月偿还本息 - 每月偿还利息
			BigDecimal monthPrincipal = monthIncome.subtract(monthInterest);

			ReplayPlan plan = new ReplayPlan(period, yearRate, monthInterest, monthPrincipal, before.toDate(),
					after.toDate(), days);
			map.put(period, plan);
		}

		return map;
	}

	public static void main(String[] args) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date begin = sdf.parse("2017-07-23");
		Map<Integer, ReplayPlan> detailPlan = new RePayAlgorithmPrincipal().getRepayPlan(3000, 0.1, 3, begin);
		System.out.println("等额本息");
		for (int i = 1; i <= detailPlan.size(); i++) {
			ReplayPlan plan = detailPlan.get(i);
			System.out.println(plan);
		}
	}
}